package com.clock.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.clock.scheduler.AlarmScheduler;
import javafx.animation.*;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.File;
import java.net.URL;
import java.time.LocalTime;
import java.util.Map;
import java.util.ResourceBundle;

@Component
public class AlarmController implements Initializable {

    private static final Logger log = LoggerFactory.getLogger(AlarmController.class);

    @FXML
    private TextField hourField, minuteField;

    @FXML
    private ComboBox<Integer> hourComboBox, minuteComboBox;

    @FXML
    private Button setButton;

    @FXML
    private Label statusLabel;

    @FXML
    private Button pauseButton;

    @FXML
    private Label marqueeLabel;

    private MediaPlayer mediaPlayer; // 用作成员变量

    /**
     * 跑马灯效果
     */
    private TranslateTransition marqueeTransition;

    /**
     * 闪烁效果
     */
    private FadeTransition blinkTransition;



    public void buttonClick(ActionEvent actionEvent) {
        try {
            // int hour = Integer.parseInt(hourField.getText());
            // int minute = Integer.parseInt(minuteField.getText());

            Integer hour = hourComboBox.getValue();
            Integer minute = minuteComboBox.getValue();

            if (hour == null || minute == null) {
                statusLabel.setText("请选择小时和分钟！");
                showAlert(Alert.AlertType.WARNING, "提示", "闹钟参数设置错误", "请选择小时和分钟！");
                return;
            }
            log.info("时间参数hour=={},minute=={}", hour, minute);

            LocalTime alarmTime = LocalTime.of(hour, minute);
            SpringUtil.getBean(AlarmScheduler.class).setAlarm(alarmTime, this::showAlert);

            statusLabel.setText("闹钟设置成功: " + alarmTime);
        } catch (Exception e) {
            log.error("时间格式错误", e);
            statusLabel.setText("时间格式错误");
        }
    }

    private static void showAlert(Alert.AlertType alertType, String title, String header, String content) {
        Alert alert = new Alert(alertType);
        alert.setTitle(title);
        alert.setHeaderText(header);
        alert.setContentText(content);
        alert.showAndWait();
    }

    private void preloadJavaFXAlert() {
        Platform.runLater(() -> {
            log.info("提前预加载弹窗");
            Alert dummy = new Alert(Alert.AlertType.NONE);
            dummy.setTitle("");
            dummy.setHeaderText(null);
            dummy.setContentText("");
            // 强制初始化内部结构
            dummy.getDialogPane().getScene();
            // 不显示，仅初始化
            dummy.close();
        });
    }

    @FXML
    public void pauseAudio() {
        if (mediaPlayer != null) {
            MediaPlayer.Status status = mediaPlayer.getStatus();
            if (status == MediaPlayer.Status.PLAYING) {
                pauseButton.setText("继续播放");
                mediaPlayer.pause();
                // 暂停跑马灯动画
                marqueeTransition.pause();
            } else if (status == MediaPlayer.Status.PAUSED) {
                mediaPlayer.play();
                pauseButton.setText("暂停播放");
                // 继续跑马灯动画
                marqueeTransition.play();
            }
        }
    }

    public void showAlert(LocalTime time) {
        Platform.runLater(() -> {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            String alarmTime = statusLabel.getText();
            log.info("alarmTime=={}", alarmTime);

            alert.setTitle("闹钟提醒");
            alert.setHeaderText("时间到了!");
            alert.setContentText("当前时间: " + time);

            Stage stage = (Stage) statusLabel.getScene().getWindow(); // 获取主窗口
            // 调用抖动
            shakeWindow(stage);
            // 调用闪烁
            flashWindow(stage);

            // ✅ 创建一个 Timeline，在10秒后关闭弹窗
            Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(10), event -> {
                alert.setResult(ButtonType.OK); // 模拟点击 OK
                alert.hide(); // 关闭弹窗
            }));
            timeline.setCycleCount(1);
            timeline.play();

            alert.showAndWait(); // 会阻塞当前线程，直到被关闭
            timeline.stop(); // 若用户手动关闭，则停止定时器

            playAlarmSound();
        });
    }


    /**
     * 抖动效果
     *
     * @param stage 主窗口
     */
    private void shakeWindow(Stage stage) {
        final int distance = 60; // 抖动幅度
        final int cycles = 20;   // 抖动次数
        final long delay = 30;   // 每次抖动间隔（毫秒）

        Platform.runLater(() -> {
            final double originalX = stage.getX();
            final double originalY = stage.getY();

            new Thread(() -> {
                try {
                    for (int i = 0; i < cycles; i++) {
                        final int offsetX = (i % 2 == 0 ? distance : -distance);
                        final int offsetY = (i % 2 == 0 ? distance : -distance);

                        Platform.runLater(() -> {
                            stage.setX(originalX + offsetX);
                            stage.setY(originalY + offsetY);
                        });

                        Thread.sleep(delay);
                    }

                    Platform.runLater(() -> {
                        stage.setX(originalX);
                        stage.setY(originalY);
                    });
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        });
    }

    /**
     * 闪烁效果
     *
     * @param stage 主窗口
     */
    private void flashWindow(Stage stage) {
        new Thread(() -> {
            try {
                for (int i = 0; i < 6; i++) {
                    Platform.runLater(() -> stage.setOpacity(0.3));
                    Thread.sleep(100);
                    Platform.runLater(() -> stage.setOpacity(1.0));
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }

    private void playAlarmSound() {
        // sudo xattr -rd com.apple.quarantine /Users/yangge/java-fx-sdk/openjfx-17.0.15_osx-aarch64_bin-sdk/javafx-sdk-17.0.15
        try {
            Media sound = new Media(new ClassPathResource("music/霹雳惊鸿之刀剑春秋-剧集原声带-醉寒江.mp3").getURL().toExternalForm());

            // 先停止之前的播放（避免重复）
            if (mediaPlayer != null) {
                mediaPlayer.stop();
            }

            mediaPlayer = new MediaPlayer(sound);
            // ✅ 设置循环播放
            mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);
            mediaPlayer.play();

            startMarquee("霹雳英雄 - 醉寒江");

            // 设置30秒后自动停止
            /*new Thread(() -> {
                try {
                    Thread.sleep(30_000);
                    Platform.runLater(() -> {
                        if (mediaPlayer != null && mediaPlayer.getStatus() == MediaPlayer.Status.PLAYING) {
                            mediaPlayer.stop();
                            pauseButton.setText("暂停播放"); // 恢复按钮文字
                        }
                    });
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();*/
        } catch (Exception e) {
            log.error("播放铃声失败", e);
        }
    }


    private void startMarquee(String text) {
        marqueeLabel.setText(text);
        marqueeLabel.setTranslateX(marqueeLabel.getScene().getWidth()); // 从右边开始

        Text tempText = new Text(text);
        tempText.setFont(marqueeLabel.getFont());
        double textWidth = tempText.getLayoutBounds().getWidth() + 2;

        double sceneWidth = marqueeLabel.getScene().getWidth() + 12;

        // 创建跑马灯动画
        marqueeTransition = new TranslateTransition();
        marqueeTransition.setNode(marqueeLabel);
        marqueeTransition.setDuration(Duration.seconds(12));
        marqueeTransition.setFromX(sceneWidth);
        marqueeTransition.setToX(-textWidth); // 往左移出视图
        marqueeTransition.setCycleCount(TranslateTransition.INDEFINITE);
        marqueeTransition.play();

        // 闪烁效果（淡入淡出）
        blinkTransition = new FadeTransition(Duration.seconds(0.5), marqueeLabel);
        blinkTransition.setFromValue(1.0);
        blinkTransition.setToValue(0.2);
        blinkTransition.setAutoReverse(true);
        blinkTransition.setCycleCount(Animation.INDEFINITE);
        blinkTransition.play();
    }

    private void stopMarquee() {
        if (marqueeTransition != null) {
            marqueeTransition.stop();
        }
        if (blinkTransition != null) {
            blinkTransition.stop();
            marqueeLabel.setOpacity(1.0); // 恢复不透明
        }
        marqueeLabel.setText("");
    }


    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        preloadJavaFXAlert();
        LocalTime now = LocalTime.now();
        int hour = now.getHour();
        int minute = now.getMinute();
        for (int i = 0; i < 24; i++) {
            hourComboBox.getItems().add(i);
        }
        for (int i = 0; i < 60; i++) {
            minuteComboBox.getItems().add(i);
        }

        hourComboBox.getSelectionModel().select(hour);
        minuteComboBox.getSelectionModel().select(minute);
    }
}
